package br.com.albatroz.dao;

import org.hibernate.Session;
import org.hibernate.ejb.HibernateEntityManager;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public abstract class AbstractDao<T> implements IDao<T> {

    protected EntityManager em;

    /**
     * @param em
     */
    @PersistenceContext
    public void setEm(EntityManager em) {
        this.em = em;
        //postInitialize();
    }

    /**
     * {@inheritDoc}
     */
    public abstract Class<T> getType();

    /**
     * {@inheritDoc}
     */
    public List<T> findAll() {
        Query query = em.createQuery("from " + getType().getName());
        return query.getResultList();
    }

    /**
     * {@inheritDoc}
     */
    public T findById(long id) {
        return em.find(getType(), id);
    }

    /**
     * {@inheritDoc}
     */
    public void store(T entity) {
        em.persist(entity);
    }

    /**
     * {@inheritDoc}
     */
    public void merge(T entity) {
        em.merge(entity);
    }

    /**
     * {@inheritDoc}
     */
    public void delete(T entity) {
        em.remove(entity);
    }

    /**
     * {@inheritDoc}
     */
    public void flush() {
        em.flush();
    }

    /**
     * {@inheritDoc}
     */
    public void deleteAll() {
        Query query = em.createQuery("delete from " + getType().getName());
        query.executeUpdate();
    }

    /**
     * Inhibits warnings about unchecked conversions. Calling this method
     * makes it unnecessary to set the @SuppressWarnings annotation in concrete
     * daos.
     *
     * @param q The query, whose result list is to be returned
     * @return A list of Ts matching the query.
     */
    protected List<T> getQueryResultList(Query q) {
        return q.getResultList();
    }

    
    /**
     * Retrieve the hibernate session object that is encapsulated
     * by the entity manager.
     *
     * @return the session object in the hibernate entity manager.
     * @throws Exception 
     */
    protected Session getSession() throws Exception {
        if (!(em instanceof HibernateEntityManager)) {
            throw new Exception("no hibernate entity manager available");
        }
        HibernateEntityManager hem = (HibernateEntityManager) em;
        return hem.getSession();
    }

}
